* @since 1.23
*/
private static function getCachedRevisionObject( $parser, $title = null ) {
- static $cache = null;
- if ( $cache == null ) {
- $cache = new MapCacheLRU( 50 );
- }
-
if ( is_null( $title ) ) {
return null;
}
// Normalize name for cache
$page = $title->getPrefixedDBkey();
- if ( $cache->has( $page ) ) { // cache contains null values
- return $cache->get( $page );
+ if ( !( $parser->currentRevisionCache && $parser->currentRevisionCache->has( $page ) )
+ && !$parser->incrementExpensiveFunctionCount() ) {
+ return null;
}
- if ( $parser->incrementExpensiveFunctionCount() ) {
- $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
- $pageID = $rev ? $rev->getPage() : 0;
- $revID = $rev ? $rev->getId() : 0;
- $cache->set( $page, $rev ); // maybe null
+ $rev = $parser->fetchCurrentRevisionOfTitle( $title );
+ $pageID = $rev ? $rev->getPage() : 0;
+ $revID = $rev ? $rev->getId() : 0;
- // Register dependency in templatelinks
- $parser->getOutput()->addTemplate( $title, $pageID, $revID );
+ // Register dependency in templatelinks
+ $parser->getOutput()->addTemplate( $title, $pageID, $revID );
- return $rev;
- }
- $cache->set( $page, null );
- return null;
+ return $rev;
}
/**
*/
public $mLangLinkLanguages;
+ /**
+ * @var MapCacheLRU|null
+ * @since 1.24
+ *
+ * A cache of the current revisions of titles. Keys are $title->getPrefixedDbKey()
+ */
+ public $currentRevisionCache;
+
/**
* @var bool Recursive call protection.
* This variable should be treated as if it were private.
$this->mVarCache = array();
$this->mUser = null;
$this->mLangLinkLanguages = array();
+ $this->currentRevisionCache = null;
/**
* Prefix for temporary replacement strings for the multipass parser.
$this->startParse( $title, $options, self::OT_HTML, $clearState );
+ $this->currentRevisionCache = null;
$this->mInputSize = strlen( $text );
if ( $this->mOptions->getEnableLimitReport() ) {
$this->mOutput->resetParseStartTime();
$this->mRevisionUser = $oldRevisionUser;
$this->mRevisionSize = $oldRevisionSize;
$this->mInputSize = false;
+ $this->currentRevisionCache = null;
wfProfileOut( $fname );
wfProfileOut( __METHOD__ );
return array( $dom, $title );
}
+ /**
+ * Fetch the current revision of a given title. Note that the revision
+ * (and even the title) may not exist in the database, so everything
+ * contributing to the output of the parser should use this method
+ * where possible, rather than getting the revisions themselves. This
+ * method also caches its results, so using it benefits performance.
+ *
+ * @since 1.24
+ * @param Title $title
+ * @return Revision
+ */
+ public function fetchCurrentRevisionOfTitle( $title ) {
+ $cacheKey = $title->getPrefixedDBkey();
+ if ( !$this->currentRevisionCache ) {
+ $this->currentRevisionCache = new MapCacheLRU( 100 );
+ }
+ if ( !$this->currentRevisionCache->has( $cacheKey ) ) {
+ $this->currentRevisionCache->set( $cacheKey,
+ // Defaults to Parser::statelessFetchRevision()
+ call_user_func( $this->mOptions->getCurrentRevisionCallback(), $title, $this )
+ );
+ }
+ return $this->currentRevisionCache->get( $cacheKey );
+ }
+
+ /**
+ * Wrapper around Revision::newFromTitle to allow passing additional parameters
+ * without passing them on to it.
+ *
+ * @since 1.24
+ * @param Title $title
+ * @param Parser|bool $parser
+ * @return Revision
+ */
+ public static function statelessFetchRevision( $title, $parser = false ) {
+ return Revision::newFromTitle( $title );
+ }
+
/**
* Fetch the unparsed text of a template and register a reference to it.
* @param Title $title
break;
}
# Get the revision
- $rev = $id
- ? Revision::newFromId( $id )
- : Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
+ if ( $id ) {
+ $rev = Revision::newFromId( $id );
+ } elseif ( $parser ) {
+ $rev = $parser->fetchCurrentRevisionOfTitle( $title );
+ } else {
+ $rev = Revision::newFromTitle( $title );
+ }
$rev_id = $rev ? $rev->getId() : 0;
# If there is no current revision, there is no page
if ( $id === false && !$rev ) {
*/
public $mRemoveComments = true;
+ /**
+ * Callback for current revision fetching. Used as first argument to call_user_func().
+ */
+ public $mCurrentRevisionCallback =
+ array( 'Parser', 'statelessFetchRevision' );
+
/**
* Callback for template fetching. Used as first argument to call_user_func().
*/
return $this->mRemoveComments;
}
+ /* @since 1.24 */
+ public function getCurrentRevisionCallback() {
+ return $this->mCurrentRevisionCallback;
+ }
+
public function getTemplateCallback() {
return $this->mTemplateCallback;
}
return wfSetVar( $this->mRemoveComments, $x );
}
+ /* @since 1.24 */
+ public function setCurrentRevisionCallback( $x ) {
+ return wfSetVar( $this->mCurrentRevisionCallback, $x );
+ }
+
public function setTemplateCallback( $x ) {
return wfSetVar( $this->mTemplateCallback, $x );
}